package it.univaq.mancoosi.injectors.systemconfiguration.ubuntu;

import it.univaq.mancoosi.injectors.systemconfiguration.managers.PackageManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuAlternativesManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuBootManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuConfigurationManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuDesktopDbManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuEmacsManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuEnvironmentManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuFileSystemManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuGConfManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuGroupManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuIconCacheManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuInformationFileManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuLibraryCacheManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuMenuManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuMimeTypeHandlerCacheManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuModuleCacheManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuPackageManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuPackageSettingDependenciesManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuSGMLCatalogManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuSkeeperCatalogManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuUdevManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuUserManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu.UbuntuXFontCacheManager;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;

import it.univaq.mancoosi.mancoosimm.Boot;
import it.univaq.mancoosi.mancoosimm.Configuration;
import it.univaq.mancoosi.mancoosimm.Environment;
import it.univaq.mancoosi.mancoosimm.FileSystem;
import it.univaq.mancoosi.mancoosimm.GConf;
import it.univaq.mancoosi.mancoosimm.MimeTypeHandlerCache;
import it.univaq.mancoosi.mancoosimm.impl.MancoosiPackageImpl;


import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;

public class Injector {
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
	
		// initialize model and dependencies
		MancoosiPackageImpl.init();
					
		Configuration configuration = null;
		//Boot boot = null;
	
		URI fileURI = URI.createFileURI("model/systemModel.mancoosimm");
		java.io.File systemModel = new java.io.File("model/systemModel.mancoosimm");
		
		PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("model/data.txt")));
		
		Resource resource = new XMIResourceFactoryImpl().createResource(fileURI);

		if (systemModel.exists()) {
			
			resource.load(null);
			UbuntuConfigurationManager.getInstance().setConfiguration( (Configuration) resource.getContents().get(0) );

			configuration = UbuntuConfigurationManager.getInstance().getConfiguration();
			UbuntuFileSystemManager.getInstance().setFileSystem(configuration.getFileSystem());
			UbuntuEnvironmentManager.getInstance().setEnvironment(configuration.getEnvironment());
			configuration.setFileSystem(UbuntuFileSystemManager.getInstance().getFileSystem());

			//UbuntuPackageManager.getInstance().removePackage("yelp");
			
			//UbuntuPackageManager.getInstance().synchronize();
			
			UbuntuFileSystemManager.getInstance().synchronize();			
			UbuntuPackageManager.getInstance().synchronize();
			UbuntuEmacsManager.getInstance().synchronize();
			UbuntuUserManager.getInstance().synchronize();
			UbuntuGroupManager.getInstance().synchronize();
			UbuntuInformationFileManager.getInstance().synchronize();
			UbuntuMenuManager.getInstance().synchronize();
			UbuntuUdevManager.getInstance().synchronize();
			UbuntuAlternativesManager.getInstance().synchronize();
			UbuntuDesktopDbManager.getInstance().synchronize();
			UbuntuIconCacheManager.getInstance().synchronize();
			UbuntuGConfManager.getInstance().synchronize();
			UbuntuLibraryCacheManager.getInstance().synchronize();
			UbuntuMimeTypeHandlerCacheManager.getInstance().synchronize();
			UbuntuBootManager.getInstance().synchronize();
			UbuntuModuleCacheManager.getInstance().synchronize();
			UbuntuXFontCacheManager.getInstance().synchronize();
			UbuntuSkeeperCatalogManager.getInstance().synchronize();
			UbuntuSGMLCatalogManager.getInstance().synchronize();
			UbuntuFileSystemManager.getInstance().deleteMissingFilesFromModel();
			
			System.out.println("Synchronization completed !");		
			
		} else {
	
			// The configuration element is initialized 
			configuration = UbuntuConfigurationManager.getInstance().getConfiguration();
			resource.getContents().add(configuration);
			
			Environment environment = UbuntuEnvironmentManager.getInstance().getEnvironment();
			FileSystem fileSystem = UbuntuFileSystemManager.getInstance().getFileSystem();
			
			configuration.setEnvironment(environment);
			configuration.setFileSystem(fileSystem);
			
			// System package are added in the model
			PackageManager pkgManager = UbuntuPackageManager.getInstance();
			out.println("* Creating package elements...");
			out.println((new GregorianCalendar()).getTime());
			
			start = new GregorianCalendar().getTimeInMillis(); 
			pkgManager.createPackageElementsFromSystem();
			printTime("pkgManager.createPackageElementsFromSystem()");
			
			out.println((new GregorianCalendar()).getTime());
			out.println("* Package elements created !");					
		
			
			
			/*
			out.println("* Retrieving package setting dependencies...");
			out.println((new GregorianCalendar()).getTime());
			//UbuntuPackageSettingDependenciesManager.getInstance().updatePackageSettingDependencies();
			out.println((new GregorianCalendar()).getTime());
			out.println("* Package settings retrieved !");
			
			// System users and groups are added in the model
			out.println("* Retrieving users and groups...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuUserManager userManager = (UbuntuUserManager) UbuntuUserManager.getInstance();
			userManager.createUsersFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* Users and groups created !");
			
			// System mime types are added in the model
			out.println("* Retrieving Mime Type Handler Cache...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuMimeTypeHandlerCacheManager.getInstance().createMimeTypeHandlerCacheFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* Mime Type Handler retrieved !");
			
			// System alternatives are added in the model
			out.println("* Retrieving Alternatives...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuAlternativesManager.getInstance().createAlternativesFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* Alternatives retrieved !");
			
			// System gconf files are added in the model
			out.println("* Retrieving GConf...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuGConfManager.getInstance().createGConfFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* GConf retrieved !");
			
			// System icon cache is added in the model
			out.println("* Retrieving IconCache...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuIconCacheManager.getInstance().createIconCacheFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* IconCache retrieved !");
			
			// System desktop DB is added in the model
			out.println("* Retrieving DesktopDB...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuDesktopDbManager.getInstance().createDesktopDbFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* DesktopDB retrieved !");
			
			// System information files are added in the model
			out.println("* Retrieving infoFile...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuInformationFileManager.getInstance().createInformationFileFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* infoFile retrieved !");
			
			// System skeeper catalog is added in the model
			out.println("* Retrieving skeeper catalog...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuSkeeperCatalogManager.getInstance().createSkeeperCatalogFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* skeeper catalog retrieved !");
			
			// System sgml catalog is added in the model
			out.println("* Retrieving sgml catalog...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuSGMLCatalogManager.getInstance().createSGMLCatalogFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* sgml catalog retrieved !");
			
			// System udev is added in the model
			out.println("* Retrieving udev...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuUdevManager.getInstance().createUdevFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* udev retrieved !");
			
			// System menu is added in the model
			out.println("* Retrieving menu...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuMenuManager.getInstance().createMenuFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* menu retrieved !");
			
			// System xfont caches are added in the model
			out.println("* Retrieving XFont Caches...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuXFontCacheManager.getInstance().createXFontCachesFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* XFont Caches retrieved !");
			
			// System library cache is added in the model
			out.println("* Retrieving libraryCache...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuLibraryCacheManager.getInstance().createLibraryCacheFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* libraryCache retrieved !");
			
			// System module caches are added in the model
			out.println("* Retrieving module caches...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuModuleCacheManager.getInstance().createModuleCachesFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* module caches retrieved !");
			
			// System boot scripts are added in the model
			out.println("* Retrieving boot scripts...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuBootManager.getInstance().createBootScriptsFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* boot scripts retrieved !");
			
			// System emacs package is added in the model
			out.println("* Retrieving Emacs Package...");
			out.println((new GregorianCalendar()).getTime());
			UbuntuEmacsManager.getInstance().createEmacsPackageFromSystem();
			out.println((new GregorianCalendar()).getTime());
			out.println("* Emacs Package retrieved !");
					*/
			out.println((new GregorianCalendar()).getTime());
			configuration.setCreationTime((new GregorianCalendar()).getTime().toString());
			configuration.setSystemType("Ubuntu");	
			out.println("Model injection completed !");
		}
		
		out.close(); 

		resource.save(Collections.EMPTY_MAP);
		
	}
	
	static double start;
	static private void printTime (String name) {
		double end = (new GregorianCalendar().getTimeInMillis() - start) / (60 * 1000);
		System.out.println(name + "  time(min)->  " + end);
	}

}
